#include "parser.h"
//#include "uart.h"
#include <stdio.h>

parser* parser_create() 
{
	parser *p = (parser*) malloc(sizeof(parser));
	p->p = (parseable*) malloc(sizeof(parseable));
	p->p->to_parse = (char*) malloc(sizeof(char));
	p->p->size = 1;
	p->p->to_parse[0] = '\0';
	return p;
}

void parse_add(parser *p, char c)
{
	char buff[20];
	sprintf(buff, "%d\n", c);
	
	char *tmp = p->p->to_parse;
	p->p->to_parse = (char*) malloc(sizeof(char) * (p->p->size + 2));
	strncpy(p->p->to_parse, tmp, p->p->size);
	p->p->to_parse[p->p->size - 1] = c;
	p->p->to_parse[p->p->size++] = '\0';
	free(tmp);
}

void add_attrib(char ***attr, char *val)
{
	int i = 0;
	char **tmp = (*attr);
	while((*attr)[i]) {
	       ++i;
	}
	(*attr) = (char**) malloc(sizeof(char*) * (i + 2));
	int j = 0;
	while(tmp[j]) {
		(*attr)[j] = tmp[j];
		++j;
	}
	(*attr)[i] = (char*) malloc(sizeof(char) * (strlen(val) + 1));
	strncpy(((*attr)[i]), val, strlen(val));
	(*attr)[i][strlen(val)] = '\0';
	(*attr)[++i] = 0;
	free(tmp);
}

int parse(parser *p)
{
	char *tag = 0;
	char **attr = (char**) malloc(sizeof(char*));
	attr[0] = 0;
	int size = p->p->size;
	char *to_parse = p->p->to_parse;
	char *end = strchr(to_parse, '\n');	// actually, \n didn't worked oO

	if(end == NULL) {
		if(attr) {
			free(attr);
		}
		return 0;
	}

	// parse it...
	char *blank = strchr(to_parse, ' ');
	if(blank == NULL) { // no attributes...
		tag = (char*) malloc(sizeof(char) * ((end - to_parse) + 1));
		strncpy(tag, to_parse, end - to_parse);
		tag[end - to_parse] = '\0';
	} else { // fill tag...
		tag = (char*) malloc(sizeof(char) * ((blank - to_parse) + 1));
		strncpy(tag, to_parse, blank - to_parse);
		tag[blank - to_parse] = '\0';
	}

	// parsing attributes...
	char *newstart = blank + 1;
	blank = strchr(newstart, ' ');
	while(blank) {
		newstart[blank - newstart] = '\0';
		add_attrib(&attr, newstart);
		newstart = blank + 1;
		blank = strchr(newstart, ' ');
	}

	// parsing last attribute...
	blank = strchr(newstart, '\n');
	newstart[blank - newstart] = '\0';
	add_attrib(&attr, newstart);
	if(p->callback) {
		p->callback(p->userdata, tag, attr);
	}

	free(p->p->to_parse);
	p->p->to_parse = (char*) malloc(sizeof(char));
	p->p->to_parse[0] = '\0';
	p->p->size = 1;
	free(tag);
	if(attr) {
		for(int i = 0; attr[i]; ++i) {
			free(attr[i]);
		}
		free(attr);
	}
	return 1;
}

void parser_delete(parser *p)
{
	free(p->p->to_parse);
	free(p->p);
	free(p);
}

